#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    i = 0;
    f = 0;
    tf = 0;
    /* 查找可用的串口 */
    find_seralport();

QMovie *movie = new QMovie("D:\\2.gif");
ui->label_2->setMovie(movie);
movie->start();
    fp_read = fopen("D:\\app.bin", "rb" );

    char buf[50] = {0xEA, 0xEB, 0xEE, 0x2C ,0x00, 0x02, 0x00, 0x00};
    memcpy(buffer, buf, 8);
    buffer[48] = 0x0D;
    buffer[49] = 0x0A;
}

MainWindow::~MainWindow()
{
    delete ui;
    killTimer(m_nTimerId);
}

/* 查找可用的串口 */
void MainWindow::find_seralport()
{

    foreach(const QSerialPortInfo &info, QSerialPortInfo::availablePorts())
    {
        QSerialPort serial;
        serial.setPort(info);
        if(serial.open(QIODevice::ReadWrite))
        {
            ui->PortBox->addItem(serial.portName());
            serial.close();
        }
    }
}

void MainWindow::on_openPortBtn_clicked()
{
    if(ui->PortBox->isEnabled())
    {
        ui->openPortBtn->setText("关闭");		//按下“OpenPort”后，按键显示为“ClosePort”
        ui->PortBox->setDisabled(true);	//按下“OpenPort”后，禁止再修改COM口
        serial.setPortName(ui->PortBox->currentText());	//设置COM口
        serial.setBaudRate(QSerialPort::Baud115200,QSerialPort::AllDirections);//设置波特率和读写方向
        serial.setDataBits(QSerialPort::Data8);		//数据位为8位
        serial.setFlowControl(QSerialPort::NoFlowControl);//无流控制
        serial.setParity(QSerialPort::NoParity);	//无校验位
        serial.setStopBits(QSerialPort::OneStop);	//一位停止位
        serial.close();					//先关串口，再打开，可以保证串口不被其它函数占用。
        if(serial.open(QIODevice::ReadWrite))		//以可读写的方式打开串口
        {
            connect(&serial,SIGNAL(readyRead()),this,SLOT(read_Com()));	//把串口的readyRead()信号绑定到read_Com()这个槽函数上
        }
//        ui->sendButton->setEnabled(true);
    }
    else
    {
        ui->openPortBtn->setText("打开");		//按下“ClosePort”后，按键显示为“OpenPort”
        ui->PortBox->setEnabled(true);		//按下“ClosePort”后，COM口可被修改
        serial.close();					//关串口
        //关闭发送按钮的使能
//        ui->sendButton->setEnabled(false);
    }
}

void MainWindow::on_pushButton_7_clicked()
{
    killTimer(m_nTimerId);
    fclose(fp_read);
    Sleep(100);
    fp_read = fopen(path.toLatin1().data(), "rb" );
    ui->label->setText("");

    i = 0;
    f = 0;

    char buf[50] = {0xEA, 0xEB, 0xEE, 0x2C ,0x00, 0x02, 0x00, 0x00};
    memcpy(buffer, buf, 8);
    buffer[48] = 0x0D;
    buffer[49] = 0x0A;

    /* 进入BootLoader */
    char buf1[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0A};
    serial.writeData(buf1, 10);
    /* 开启定时器 */
    m_nTimerId = startTimer(1000);
}

/* 手动添加的槽函数声明,用于读出串口缓冲区的内容 */
void MainWindow::read_Com()
{
    QByteArray buf;
    /* 信号到来，读取所有的字符串 */
    buf = serial.readAll();

    /* 如果真的有数据 */
    if(!buf.isEmpty())
    {
        /* 显示接收数据 */
        user_display(buf.data(),buf.size());

        /* 屏蔽第一条指令 */
        f++;
        if(f == 1)
            return;

        /* 包标识 */
        buffer[4] = i % 63;
        /* 已发送的字节数 */
        buffer[8] = i * 36 / 256;
        buffer[9] = i * 36 % 256;
        CheckSum = 0;
        qDebug() << "intCheckSum = " << CheckSum;
        if((ret = fread(buffer + 10, 1, 36, fp_read)) == 36)
        {
            tf = 0;
            qDebug() << ret;
            qDebug() <<  buffer;

            for(int j = 0; j < 36; j++)
            {
                CheckSum +=  (uint8_t)buffer[10 + j];
                qDebug() << "buffer" << j << "= " << buffer[10 + j];
                qDebug() << "CheckSum = " << CheckSum;
            }
            buffer[46] = CheckSum / 256;
            buffer[47] = CheckSum % 256;
            CheckSum = 0;

            serial.write(buffer, 50);
        }
        else if(ret != 0)
        {
            tf = 6;
            qDebug() << ret;
            buffer[3] = buffer[3] - 36 + ret;

            for(int j = 0; j < ret; j++)
            {
                CheckSum +=  (uint8_t)buffer[10 + j];
            }
            buffer[10 + ret] = CheckSum / 256;
            buffer[10 + ret + 1] = CheckSum % 256;
            CheckSum = 0;

            buffer[10 + ret + 2] = 0x0D;
            buffer[10 + ret + 3] = 0x0A;
            serial.write(buffer, 10 + ret + 2 + 2);
        }
        else
        {
            return;
        }
        i++;
//      Sleep(100);

    }
    buf.clear();
}

/* 定时器服务函数 */
void MainWindow::timerEvent( QTimerEvent *event )
{
//serial.write("buf", 3);
//    qDebug( "timer event, id %d",event->timerId() );
    qDebug() << "tf = " << tf;
    tf++;
    if(tf > 2 && tf < 5)
        serial.write(buffer, 50);
    if(tf == 5)
        ui->label->setText("刷机失败");
    if(tf == 8)
    {
        /* 启动APP */
        char buf1[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x03, 0x00, 0x00, 0x0D, 0x0A};
        serial.writeData(buf1, 10);
        ui->label->setText("刷机成功");
    }

}

void MainWindow::on_pushButton_clicked()
{
//    /* 启动APP */
//    char buf1[10] = {0xEA, 0xEB, 0xEE, 0x04, 0x00, 0x03, 0x00, 0x00, 0x0D, 0x0A};
//    serial.writeData(buf1, 10);

    path = QFileDialog::getOpenFileName(this, tr("Open File"), ".", tr("All Files(*.*)"));
    if(path.length() == 0) {
            QMessageBox::information(NULL, tr("Path"), tr("You didn't select any files."));
    } else {
            QMessageBox::information(NULL, tr("Path"), tr("You selected ") + path);
    }
}


/* 16进制字符数组转字符串并显示 */
void MainWindow::user_display(char *s, int size)
{
    QByteArray a;   /* 转换成QByteArray是为了能够toHex() */
    a.resize(10);
    for(int i = 0; i < size; i++)
    {
        a[i] = s[i];
    }

    QString b(a.toHex().toUpper());     /* 转换成字符串是为了能够插入空格 */
    for(int i = size - 1; i >= 0; i--)
    {
        b.insert(i * 2," ");
    }
    ui->label_10->clear();
    ui->label_10->setText("成功接收 " + b);
    qDebug() << b;
}


